package Static_Final;/*
 *
 * @author 陈粒
 * @version 创建时间：2021/7/8 11:41
 */

/**
 * 在Java中static表示“全局”或者“静态”的意思，用来修饰成员变量和成员方法，当然也可以修饰代码块。
 * 注意：static修饰的变量叫类变量也叫静态变量
 * 作用：方便在没有创建对象的情况下进行调用(方法/变量)。
 * 注意：静态方法不能访问非静态成员方法和非静态成员变量，
 *      非静态成员方法可以访问静态成员方法和静态成员变量
 * 一、修饰成员变量：
 * static只能修饰成员变量，修饰的变量叫static变量或静态变量，静态变量和非静态变量的区别：
 * 静态变量被所有对象共享，在内存中只有一个副本，在类初次加载的时候才会初始化
 * 非静态变量是对象所拥有的，在创建对象的时候被初始化，存在多个副本，各个对象拥有的副本互不影响
 * 注意：static成员变量初始化顺序按照定义的顺序来进行初始化
 * 二、修饰成员方法：
 * static方法也成为静态方法，静态方法不依赖于任何对象就可以直接访问，所以静态方法中不能用this
 * 特别说明：static方法是属于类的，非实例对象，在JVM加载类时，就已经存在内存中，
 * 不会被虚拟机GC回收掉，会持续占用内存，使内存负荷增加，但是非static方法会在运行完毕后被虚拟机GC掉，减轻内存压力。
 * 三、修饰代码块：
 *  静态代码块用于对类的初始化操作，在静态代码块中，不能访问非静态的成员
 *  作用：提升程序性能
 *  注意：
 *  静态初始化块可以置于类中的任何地方，类中可以有多个静态初始化块。
 *  在类初次被加载时，会按照静态初始化块的顺序来执行每个块，并且只会执行一次。
 *  四、继承关系下的静态代码块：
 *  父类和子类都有静态代码块的情况，先执行父类的静态代码块，再执行子类的
 */
public class Static {
    public static void main(String[] args) {
        System.out.println("静态变量a：" + Static1.a + " " + "静态变量s：" + Static1.s);
        System.out.println("--------------");
        //主函数是静态方法，可以调用类Static1的静态变量
        Static2.Test2();//调用静态方法
        System.out.println("--------------");
        new Static3();//创建类Static3的对象，将类加载进内存，从而调用静态代码块
        System.out.println("--------------");
        new Son();
    }
}

class Static1 {
    static int a = 0;//静态变量a
    static String s = "abc";//静态变量s
    double b = 0.2;
}
class Static2{
    static void Test2(){//静态方法
        System.out.println("静态方法");
    }
}
class Static3{
    static{
        System.out.println("类的第1个静态代码块");//静态代码块
    }
    static{
        System.out.println("类的第2个静态代码块");//静态代码块
    }
}
class Son extends Father{
    static{
        System.out.println("子类静态代码块");
    }

    public Son() {
        //隐式的写有super();调用父类无参构造函数，子类所有构造函数都有这个语句
        System.out.println("子类无参构造函数");
    }
}
class Father{
    static{
        System.out.println("父类静态代码块");
    }

    public Father() {
        System.out.println("父类无参构造函数");
    }
}
